class EventController < ApplicationController
  
  before_filter :login_required, :except => [:add_assignment, :rate_answer]
  before_filter :instructor_required, :only => [:add_assignment, :rate_answer]

  # Muestra los eventos que uno a creado o todos los eventos si eres
  # administrador.
  def list_own
    if not self.is_admin?
      @event_pages = Paginator.new(self, self.current_user.events.size, 10, params[:page])
      @to_list = self.current_user.events[@event_pages.current.offset..@event_pages.current.last_item]
    else
      @event_pages, @to_list = paginate(:events)
    end
  end

  # Lista todos los assignments de un curso.
  def list_assignments
    if params[:id].nil?
      flash[:error] = "Necesito un id mostrar las asignaciones."
      redirect_to :controller => 'account', :action => 'index'
      return
    end
    @to_list = Course.find(params[:id]).assignments.sort { |a,b| a.due_date <=> b.due_date }
    render :action => 'list_own'
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "Curso desconocido: #{params[:id]}."
    redirect_to :controller => 'account', :action => 'index'
  end

  # Lista todos los eventos de un curso.
  def list_events
    if params[:id].nil?
      flash[:error] = "Necesito un id mostrar los eventos."
      redirect_to :controller => 'account', :action => 'index'
      return
    end
    course = Course.find(params[:id])
    @event_pages = Paginator.new(self, course.events.size, 10, params[:page])
    @to_list = course.events.sort { |a,b| a.due_date <=> b.due_date }[@event_pages.current.offset..@event_pages.current.last_item]
    render :action => 'list_own'
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "Curso desconocido: #{params[:id]}."
    redirect_to :controller => 'account', :action => 'index'
  end

  # Recibe un ID, y muestra el Evento con id ID a detalle:
  #  NOMBRE del evento
  #  Curso relacionado (nombre)
  #  Fecha de ocurrencia (due_date)
  #  Fecha de finalización (expire_date)
  #  Descripcion (si es un archivo, una liga para bajarlo, si no, la descripción
  #  completa, in-line)
  #
  def view
    @to_view = Event.find(params[:id], :include => :course, :order => "due_date DESC")
    if @to_view.kind != 1
      @description = @to_view.event_blob
    else
      @description = @to_view.event_blob.id 
    end
    if @to_view.is_a?(Assignment)
      if not self.is_student?
        @answers = @to_view.assignment_answers
      else
        @assignment_answer = self.current_user.assignment_answers.select { |a| a.assignment == @to_view }[0]
      end
    end
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "Evento desconocido! #{params[:id]}"
    redirect_to :controller => 'account', :action => 'index'
  end

  # Recibe un ID, y descarga la descripcion del archivo
  def get
    @desc = EventBlob.find(params[:id])
    send_data @desc.data, :filename => @desc.file_name 
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "No puedo encontrar la descripcion: #{params[:id]}"
    redirect_to :controller => 'account', :action => 'index'
  end

  # Muestra la respuesta de una tarea o descarga la respuesta si se trataba de
  # un archivo.
  def get_answer
    @answer = AssignmentAnswer.find(params[:id])
    @desc = @answer.answer_blob
    if @answer.kind == 1
      send_data @desc.data, :filename => @desc.file_name 
      return
    end
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "No puedo encontrar la respuesta: #{params[:id]}"
    redirect_to :controller => 'account', :action => 'index'
  end

  # Califica la respuesta de una tarea.
  def rate_answer
    if not request.xhr? #No es AJAX
      return if not request.post?
      redirect_back_or_default(:controller => 'account', :action => 'index')
    end
    @answer = AssignmentAnswer.find(params[:id]);
    @answer.grade = params[:grade]
    @answer.grader = self.current_user
    if @answer.save
      if request.xhr?
        render(:text => "Calificaci&oacute;n guardada.")
      end
      return
    else
      if request.xhr?
        render(:text => "Error guardando la calificaci&oacute;n") if request.xhr?
      else
        flash[:error] = "Error guardando la calificaci&oacute;n" if not request.xhr?
      end
    end
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "No puedo encontrar la respuesta: #{params[:id]}" if not request.xhr?
    render(:text => "No puedo encontrar la respuesta: #{params[:id]}") if request.xhr?
  end

  # Crea un nuevo evento (relacionado con un curso con id = params[:id]
  def add
    if params[:id].nil?
      flash[:error] = "No pude encontrar el curso sin id."

      redirect_to(:controller => 'account', :action => 'index') 
      return 
    end
    @assignment = false
    @desc = Event.new(params[:desc])
    @desc.course = Course.find(params[:id])

    if not @desc.course.users.include?(self.current_user) and not @desc.course.creator == self.current_user and not self.is_admin?
      self.access_denied 
      return 
    end

    @desc.user = self.current_user
    @desc_data = EventBlob.new(params[:desc_data])
    @desc_data.event = @desc

    return if not request.post?

    @desc_data.event = @desc
    Event.transaction {
      @desc.save!
      @desc_data.save!
    } 
    if @desc.course.name == "Eventos Globales"
      expire_fragment( /calendar.*/ )
    else
      @desc.course.users.each {  |u|
        expire_fragment( :controller => 'calendar', :action => u.id )
      }
      expire_fragment( :controller => 'calendar', :action => @desc.course.creator.id )
    end
    redirect_to :controller => 'course', :action => 'show', :id => params[:id]
  rescue ActiveRecord::RecordInvalid
#  rescue Exception => e
#    flash[:error] = e.backtrace().join("\n")
  end

  # Crea una nueva assignacion (relacionado con un curso con id = params[:id]
  def add_assignment
    @assignment = true
    if params[:id].nil?
      flash[:error] = "No pude encontrar el curso sin id."

      redirect_to(:controller => 'account', :action => 'index') 
      return 
    end
    @desc = Assignment.new(params[:desc])
    @desc.course = Course.find(params[:id])

    # Tienes que ser parte del curso (o haberlo creado)
    if not @desc.course.users.include?(self.current_user) and
      not @desc.course.creator == self.current_user and
      not self.is_admin?

      self.access_denied 
      return 
    end

    @desc.user = self.current_user
    @desc_data = EventBlob.new(params[:desc_data])
    @desc_data.assignment = @desc
    
    return if not request.post?

    Assignment.transaction {
      @desc.save!
      @desc_data.save!
    } 
    redirect_to :controller => 'course', :action => 'show', :id => params[:id]
  rescue ActiveRecord::RecordInvalid
#  rescue Exception => e
#    flash[:error] = e.backtrace().join("\n")
  end

  def remove
    if params[:id].nil?
      flash[:error] = "ID desconocido: nil"
    else
      event = Event.find(params[:id])
      if not (self.is_admin? or self.current_user != event.user)
        access_denied
        return
      elsif request.post?
        flash[:notice] = "Evento #{event.name} borrado con éxito"
        event.destroy
      else
        flash[:notice] = "Evento sin borrar."
      end
    end
    redirect_to :controller => 'event', :action => 'list_own'
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "ID desconocido: #{params[:id]}"
    redirect_to :controller => 'event', :action => 'list_own'
  end

  # Responder a una tarea.
  def answer_assignment
    if params[:id].nil?
      flash[:error]="No conozco la asignación: nil"
      redirect_to :controller => 'course', :action => 'list' 
      return
    end
    @assignment = Assignment.find(params[:id])
    if @assignment.expire_date < Time.now
      flash[:error] = "La asignación está cerrada."
      redirect_back_or_default :controller => 'course', :action => 'list' 
      return
    end

    @assignment_answer = AssignmentAnswer.find(:first, :conditions => { :assignment_id => @assignment, :user_id => self.current_user })
    @assignment_answer ||= AssignmentAnswer.new()
    @assignment_answer.attributes = params[:assignment_answer]
    @answer_blob = @assignment_answer.answer_blob
    @answer_blob ||= AnswerBlob.new()
    @assignment_answer.answer_blob = @answer_blob
    @assignment_answer.assignment = @assignment
    @assignment_answer.user = self.current_user
    @answer_blob.attributes = params[:answer_blob]
    logger.debug(@answer_blob.to_yaml)
    logger.debug(@assignment_answer.to_yaml)
    return if not request.post?

    AssignmentAnswer.transaction {
      @answer_blob.save!
      @assignment_answer.save!
    }
    redirect_to :controller => 'event', :action => 'view', :id => params[:id]
  rescue ActiveRecord::RecordNotFound
    flash[:error] = "ID desconocido: #{params[:id]}"
    redirect_to :controller => 'course', :action => 'list' 
  rescue ActiveRecord::RecordInvalid
    flash[:error] = "Record Invalid!"
    redirect_to :controller => 'event', :action => 'view', :id => params[:id]
  end
end
